package particlesystem.graphics {
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	import flash.utils.getDefinitionByName;

	/**
	 * @author robertthurston
	 */
	public class BitmapAnimationFactory {

		private var animations : Dictionary;

		public function BitmapAnimationFactory() {
			animations = new Dictionary();
		}

		public function getBitmapAnimationArray(linkages : Array) : Array {
			var array : Array = new Array();
			
			for(var i : int = 0;i < linkages.length;i++) {
				array.push(getBitmapAnimation(linkages[i]));
			}
			
			return array;
		}

		public function getBitmapAnimation(linkage : String) : Array {
			var animation : Array;
			
			if(animations[linkage]) {
				animation = animations[linkage];
			} else {
				animation = createAnimation(linkage);
				animations[linkage] = animation;
			}
			
			return animation;
		}

		private function createAnimation(linkage : String) : Array {
			var mc : MovieClip = new (getDefinitionByName(linkage))() as MovieClip;
			
			return buildAnimation(mc);
		}

		private function buildAnimation(mc : MovieClip) : Array {
			var animation : Array = new Array;
			var bounds : Rectangle = getBounds(mc);
			
			for(var i : int = 0;i < mc.totalFrames;i++) {
				mc.gotoAndStop(i + 1);
				animation.push(createFrameBitmapData(mc, bounds));
			}
			
			return animation;
		}

		private function getBounds(mc : MovieClip) : Rectangle {
			var bounds : Rectangle = new Rectangle();
			var boundsToCheck : Rectangle;
			
			for(var i : int = 0;i < mc.totalFrames;i++) {
				mc.gotoAndStop(i + 1);
				boundsToCheck = mc.getBounds(mc);
				
				if(boundsToCheck.x < bounds.x) {
					bounds.x = boundsToCheck.x;
				}
				
				if(boundsToCheck.y < bounds.y) {
					bounds.y = boundsToCheck.y;
				}
				
				if(boundsToCheck.width > bounds.width) {
					bounds.width = boundsToCheck.width;
				}
				
				if(boundsToCheck.height > bounds.height) {
					bounds.height = boundsToCheck.height;
				}
			}
			
			return bounds;
		}

		private function createFrameBitmapData(frame : MovieClip, bounds : Rectangle) : BitmapData {
			var bitmapData : BitmapData = new BitmapData(bounds.width, bounds.height, true, 0x00000000);
			var matrix : Matrix = new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y);
			
			bitmapData.draw(frame, matrix);
			
			return bitmapData;
		}
	}
}
